<template>
  <div class="newTree troila-form" @click.stop>
    <el-popover
      popper-class="troila-treeBox troila-form"
      placement="bottom"
      transition="el-zoom-in-top"
      trigger="manual"
      v-model="show"
      :offset="offset"
      :width="width"
      :disabled="disabled"
    >
      <div
        ref="treeF"
        @click="disabled ? null : judgeShow(true)"
        slot="reference"
        class="treeResult el-input__inner"
        :class="{ is_focus: !disabled && show, disabled: disabled }"
        @mouseenter="changeIcon(false)"
        @mouseleave="changeIcon(true)"
      >
        <i v-if="placeholder && result.length === 0">{{ placeholder }}</i
        ><unit-over
          :content="returnResult(this.label).join(' / ')"
          v-if="returnResult(this.label).length > 0"
        ></unit-over
        ><span class="el-input__suffix"
          ><span class="el-input__suffix-inner"
            ><i
              class="el-select__caret el-input__icon el-icon-arrow-up"
              v-show="
                !(clear !== undefined && clear !== false) ||
                (clear !== undefined &&
                  clear !== false &&
                  (showIcon || result.length === 0))
              "
            ></i
            ><i
              class="el-select__caret el-input__icon el-icon-circle-close"
              v-if="
                clear !== undefined &&
                clear !== false &&
                result.length > 0 &&
                !showIcon
              "
              @click.stop="clearRes"
            ></i></span
        ></span>
      </div>
      <el-input
        v-model="inputTxt"
        @click="judgeShow"
        placeholder="筛选"
        v-if="list && list.length > 0 && input !== undefined && input !== false"
        clearable
      ></el-input>
      <p class="el-select-dropdown__empty" v-if="!list || list.length === 0">
        无数据
      </p>
      <el-scrollbar v-if="list && list.length > 0">
        <el-tree
          class="troila-popper"
          @check="getCheck"
          :data="list"
          show-checkbox
          default-expand-all
          :expand-on-click-node="
            onlyleave !== undefined &&
            onlyleave !== false &&
            !(relation !== undefined && relation !== false)
              ? true
              : false
          "
          :check-on-click-node="
            (onlyone !== undefined && onlyone !== false) ||
            (onlyleave !== undefined &&
              onlyleave !== false &&
              !(relation !== undefined && relation !== false))
              ? true
              : false
          "
          :class="{
            hidParent:
              onlyleave !== undefined &&
              onlyleave !== false &&
              !(relation !== undefined && relation !== false),
          }"
          :check-strictly="
            relation !== undefined && relation !== false ? false : true
          "
          :node-key="keyid"
          :props="{
            children: this.children,
            label: this.label,
            disabled: this.disabled_,
          }"
          :filter-node-method="filterNode"
          ref="tree"
          :highlight-current="!(onlyone !== undefined && onlyone !== false)"
        ></el-tree>
        <!-- expand-on-click-node 是否在点击节点的时候展开或者收缩节点 -->
        <!-- check-on-click-node 是否在点击节点的时候选中节点 -->
      </el-scrollbar>
    </el-popover>
  </div>
</template>

<script>
import unitOver from './over'
export default {
  name: 'treebox',
  props: [
    'list',
    'id',
    'placeholder',
    'choose',
    'onlyleave',
    'relation',
    'clear',
    'input',
    'must',
    'onlyone',
    'option',
    'disabled',
  ],
  components: {
    unitOver,
  },
  data() {
    return {
      name: new Date().valueOf() + Math.floor(Math.random() * 1000000),
      inputTxt: '',
      showIcon: true,
      show: false,
      width: 300,
      offset: 0,
      result: this.choose ? this.getRes(this.list.concat()) : [],
      keyid: this.option && this.option.key ? this.option.key : 'value',
      label: this.option && this.option.label ? this.option.label : 'label',
      children:
        this.option && this.option.children ? this.option.children : 'children',
      disabled_:
        this.option && this.option.disabled ? this.option.disabled : 'disabled',
    }
  },
  computed: {
    treebox() {
      return this.$store.state.treebox
    },
  },
  model: {
    prop: 'choose',
    event: 'input',
  },
  watch: {
    choose: {
      deep: true,
      handler() {
        this.result = this.getRes(this.list.concat())
      },
    },
    result: {
      deep: true,
      handler() {
        // console.log(this.result,this.returnResult("id"))
        // console.log(this.result,this.returnResult(this.keyid))
        this.$refs.tree
          ? this.$refs.tree.setCheckedKeys(this.returnResult(this.keyid))
          : null
      },
    },
    list: {
      deep: true,
      handler() {
        this.result = this.getRes(this.list.concat())
      },
    },
    inputTxt: {
      deep: true,
      handler(val) {
        if (val || val === '') {
          // console.log(val)
          this.$refs.tree ? this.$refs.tree.filter(val) : null
        }
      },
    },
    show(v) {
      if (v) {
        this.inputTxt = ''
        let w = this.$refs.treeF.offsetWidth
        // this.width=Math.ceil(w/2)*2;
        this.offset = w < this.width ? (this.width - w) / 2 : 0
        this.$store.commit('treeboxFn', this.name)
      }
    },
    treebox(v) {
      v !== this.name ? (this.show = false) : null
    },
  },
  methods: {
    judgeShow(j) {
      if (j === true) {
        this.show = !this.show
      } else {
        this.show = true
      }
      // console.log(this.show)
      this.show && this.list && this.list.length > 0
        ? this.$nextTick(() => {
            // console.log(this.result,this.returnResult("id"))
            this.$refs.tree.setCheckedKeys(this.returnResult(this.keyid))
          })
        : null
    },
    listenClick(e) {
      this.show ? (this.show = false) : null
    },
    clearRes() {
      this.result = []
      this.$emit('return', this.result, this.id ? this.id : 'treebox')
      let ids = this.result.map((v) => v[this.keyid])
      this.$emit(
        'input',
        typeof this.choose == 'string' || typeof this.choose == 'number'
          ? ids.join(',')
          : ids
      )
    },
    getCheck(item, choose) {
      // console.log(item,choose,this.$refs.tree.getCheckedNodes(true))
      let arr = this.$refs.tree.getCheckedNodes(
        this.onlyleave !== undefined && this.onlyleave !== false ? true : false
      )
      if (this.onlyone !== undefined && this.onlyone !== false) {
        this.result = [item]
        this.show ? (this.show = false) : null
      } else {
        this.result =
          this.must !== undefined && this.must !== false
            ? arr.length === 0
              ? [item]
              : arr
            : arr
      }
      this.$emit('return', this.result, this.id ? this.id : 'treebox')
      let ids = this.result.map((v) => v[this.keyid])
      this.$emit(
        'input',
        typeof this.choose == 'string' || typeof this.choose == 'number'
          ? ids.join(',')
          : ids
      )
    },
    returnResult(k) {
      let label = []
      this.result.map((v) => {
        label.push(v[k])
      })
      return label
    },
    getRes(list) {
      let arr = []
      let choose =
        !this.choose && this.choose !== 0
          ? []
          : typeof this.choose == 'string' || typeof this.choose == 'number'
          ? [...this.choose.toString().split(',')]
          : [...this.choose]
      if (list.length > 0 && typeof list[0][this.keyid] == 'number') {
        choose = choose.map((v) => Number(v))
      }
      list.map((v) => {
        if (choose.indexOf(v[this.keyid]) !== -1) {
          arr.push(v)
        }
        arr = arr.concat(
          v[this.children] && v[this.children].length > 0
            ? this.getRes(v[this.children])
            : []
        )
      })
      return arr
    },
    changeIcon(j) {
      this.clear !== undefined && this.clear !== false
        ? (this.showIcon = j)
        : null
    },
    filterNode(value, data) {
      // console.log(value,data)
      if (!value) return true
      return data[this.label].indexOf(value) !== -1
    },
  },
  mounted() {
    this.choose ? (this.result = this.getRes(this.list.concat())) : null
    window.addEventListener('click', this.listenClick)
  },
  destroyed() {
    window.removeEventListener('click', this.listenClick)
  },
}
</script>


<style scoped>
.newTree {
  width: 177px;
  height: 30px;
  position: relative;
  line-height: 28px;
  font-size: 14px;
  padding: 0;
}
.newTree.auto {
  width: 100%;
}
.newTree .treeResult {
  cursor: pointer;
  padding-right: 30px;
  position: relative;
}
.newTree .treeResult.disabled {
  background-color: #f5f7fa;
  border-color: #e4e7ed;
  color: #c0c4cc;
  cursor: not-allowed;
}
.newTree .treeResult > i {
  color: #c0c4cc;
  line-height: 30px;
  display: inline-block;
  vertical-align: top;
  white-space: nowrap;
  width: 100%;
  overflow: hidden;
  font-style: normal;
}
.newTree .el-select__caret {
  color: #c0c4cc;
}
.newTree .treeResult > div {
  display: block;
  float: left;
  width: 100%;
  line-height: 28px;
}
.newTree .treeResult:not(.is_focus) > span i:not(.el-icon-circle-close) {
  transform: rotateZ(180deg);
}
.newTree .treeResult > span {
  top: -1px;
  height: 30px;
}
.newTree .treeResult:not(.is_focus) > span i:not(.el-icon-circle-close) {
  transition: opacity 0.2s ease, transform 0.2s ease,
    -webkit-transform 0.2s ease;
  /* opacity: 0.6; */
  line-height: 30px;
  vertical-align: top;
}
</style>
<style>
.troila-treeBox {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  /* transform: translateX(-12px); */
  border-color: #e4e7ed;
  padding: 5px 0;
}
.troila-treeBox .el-scrollbar__wrap {
  max-height: 200px;
}
.troila-treeBox .el-tree__empty-block {
  padding: 10px 0;
  height: 60px;
  line-height: 40px;
  margin: 0;
  text-align: center;
}
.troila-treeBox .el-tree__empty-block > .el-tree__empty-text {
  color: #999;
  font-size: 14px;
  top: 40%;
}
.troila-treeBox > div {
  position: relative;
  width: 100%;
  border-radius: 2px;
}
.troila-treeBox .el-input__inner {
  width: calc(100% - 24px);
  height: 28px;
  margin: 6px 12px 4px;
  padding: 0 28px 0 14px;
  border-radius: 3px;
}
.troila-treeBox .el-input__suffix {
  margin-right: 4px;
  line-height: 40px;
}
.troila-treeBox .el-checkbox {
  margin-right: 6px;
}
.troila-treeBox .popper__arrow {
  left: 35px !important;
}
.troila-treeBox
  .hidParent
  .el-tree-node__expand-icon:not(.is-leaf)
  + .el-checkbox {
  display: none;
}
.troila-treeBox .el-scrollbar__wrap {
  margin-bottom: 0 !important;
}
.troila-treeBox
  .el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  background-color: #f2f6ff;
}
</style>